package com.ddxz.tool.http.factory;

import com.alibaba.fastjson.JSONObject;
import com.ddxz.tool.http.exception.HttpClientException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;

import java.util.HashMap;
import java.util.Map;

/**
 * interface description
 *
 * @author 朱宗刚
 * @version 1.0.0
 * @date 2020/11/30
 */

public abstract class AbstractDdxzHttpRequest {
    public JSONObject restRequest(String url) {
        return restRequest(url, null, null);
    }

    public JSONObject restRequest(String url, Map params){
        return restRequest(url, params, null);
    }

    public JSONObject restRequest(String url, Map params, Map headers){
        return restRequest(url, params, headers, null);
    }

    public JSONObject restRequest(String url, Map params, Map headers, Object entity){
        String rst = null;
        try {
            if(headers != null) {
                headers.put(CONTENT_TYPE, HEADER_JSON);
                rst = otherRequest(url, params, headers, entity);
            } else {
                rst = otherRequest(url, params, new HashMap<String, Object>(){{put(CONTENT_TYPE, HEADER_JSON);}}, entity);
            }
            return JSONObject.parseObject(rst);
        } catch (Exception e) {
            throw new HttpClientException(rst, e);
        }
    }

    public <T> T restRequest(Class<T> clz, String url){
        JSONObject rst = restRequest(url);
        return rst == null ? null : JSONObject.toJavaObject(rst, clz);
    }

    public <T> T restRequest(Class<T> clz, String url, Map params){
        JSONObject rst = restRequest(url, params);
        return rst == null ? null : JSONObject.toJavaObject(rst, clz);
    }

    public <T> T restRequest(Class<T> clz, String url, Map params, Map headers){
        JSONObject rst = restRequest(url, params, headers);
        return rst == null ? null : JSONObject.toJavaObject(rst, clz);
    }

    public <T> T restRequest(Class<T> clz, String url, Map params, Map headers, Map entity){
        JSONObject rst = restRequest(url, params, headers, entity);
        return rst == null ? null : JSONObject.toJavaObject(rst, clz);
    }

    public JSONObject normalRequest(String url){
        return normalRequest(url, null, null, null);
    }

    public JSONObject normalRequest(String url, Map params){
        return normalRequest(url, params, null, null);
    }

    public JSONObject normalRequest(String url, Map params, Map headers){
        return normalRequest(url, params, headers, null);
    }

    public JSONObject normalRequest(String url, Map params, Map headers, Map entity){
        String rst = null;
        try {
            if(headers != null) {
                headers.put(CONTENT_TYPE, HEADER_XML);
                rst = otherRequest(url, params, headers, entity);
            } else {
                rst = otherRequest(url, params, new HashMap<String, MediaType>(){{put(CONTENT_TYPE, HEADER_XML);}}, entity);
            }
            return JSONObject.parseObject(rst);
        } catch (Exception e) {
            throw new HttpClientException(rst, e);
        }
    }

    public <T> T normalRequest(Class<T> clz, String url){
        JSONObject rst = normalRequest(url);
        return rst == null ? null : rst.toJavaObject(clz);
    }

    public <T> T normalRequest(Class<T> clz, String url, Map params){
        JSONObject rst = normalRequest(url, params);
        return rst == null ? null : rst.toJavaObject(clz);
    }

    public <T> T normalRequest(Class<T> clz, String url, Map params, Map headers){
        JSONObject rst = normalRequest(url, params, headers);
        return rst == null ? null : rst.toJavaObject(clz);
    }

    public <T> T normalRequest(Class<T> clz, String url, Map params, Map headers, Map entity){
        JSONObject rst = normalRequest(url, params, headers, entity);
        return rst == null ? null : rst.toJavaObject(clz);
    }

    public String otherRequest(String url){
        return otherRequest(url, null, null, null);
    }

    public String otherRequest(String url, Map params){
        return otherRequest(url, params, null, null);
    }

    public String otherRequest(String url, Map params, Map headers){
        return otherRequest(url, params, headers, null);
    }

    public String otherRequest(String url, Map params, Map headers, Object entity){
        return doRequest(generatorUrl(url, params), headers, entity);
    }

    public abstract String doRequest(String url, Map headers, Object entity);

    private String generatorUrl(String url, Map params) {
        if(params == null) {
            return url;
        }

        StringBuilder builder = new StringBuilder();
        if(url.contains(PATH_DELIMITER)) {
            params.forEach((key, val) -> builder.append("&").append(key).append("=").append(val.toString()));
        } else {
            params.forEach((key, val) -> builder.append(builder.length() == 0 ? "?" : "&").append(key).append("=").append(val.toString()));
        }

        return builder.toString();
    }

    protected static final MediaType HEADER_JSON = MediaType.parse("application/json; charset=utf-8");
    protected static final MediaType HEADER_XML = MediaType.parse("application/xml; charset=utf-8");
    protected static final String CONTENT_TYPE = "Content-type";
    protected static final String PATH_DELIMITER = "?";

    protected OkHttpClient client;

    public AbstractDdxzHttpRequest(OkHttpClient client) {
        this.client = client;
    }
}
